package org.correct.util;

/**
 * This class is dangerous, because it does not consider synchronization between
 * threads.
 * 
 * @author Li Yujia
 *
 * @param <E> Type of the elements stored in the queue.
 */
public class Queue<E> {
	private ListNode<E> head;
	private ListNode<E> tail;
	private int size;
	
	public Queue() {
		size = 0;
		head = null;
		tail = null;
	}
	
	public synchronized void add(E e) {
		if(size == 0) {
			head = new ListNode<E>(e);
			tail = head;
		} else {
			ListNode<E> p = new ListNode<E>(e);
			tail.setNext(p);
			tail = p;
		}
		size++;
	}
	
	/**
	 * Retrieve the head of the queue, but does not remove it. If the
	 * queue is empty, return null.
	 * 
	 * @return The element at the head of the queue.
	 */
	public synchronized E peek() {
		if(head == null)
			return null;
		else
			return head.getElement();
	}
	
	/**
	 * Retrieve and remove the head of the queue. If the queue is empty,
	 * return null.
	 * 
	 * @return The element of at the head of the queue.
	 */
	public synchronized E poll() {
		if(head == null)
			return null;
		else {
			ListNode<E> p = head;
			if(head == tail) {
				head = null;
				tail = null;
			} else {
				head = head.getNext();
				p.setNext(null);
			}
			size--;
			return p.getElement();
		}
	}
	
	public synchronized int size() {
		return size;
	}
}
